import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
import { Store } from '@ngrx/store';

import { State, UserLogout, LoadUserInfoSuccess } from '../../../store';
import * as fromUserState from '../../../store/selectors/user.selector';
import { ProfileForm } from './profile.model';
import { UserInfo, UserToken } from '../../../shared/modes';
import { UserService } from '../../services';
import { NzModalService, NzNotificationService } from 'ng-zorro-antd';
import { ResetPasswordComponent } from '../reset-password/reset-password.component';
import { LocalstoreService } from '../../../shared/services';
import { Subscription } from 'rxjs';
import { ResponseError } from '../../../shared';

@Component({
  selector: 'ege-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.scss']
})
export class ProfileComponent implements OnInit, OnDestroy {

  loading: boolean = false;
  userId: string;
  userInfo: UserInfo;
  profile: ProfileForm[];
  forms: FormGroup;
  edit: boolean = false;

  private subscriptions: Subscription[] = [];

  constructor(
    private router: Router,
    private store: Store<State>,
    private fb: FormBuilder,
    private modalService: NzModalService,
    private notification: NzNotificationService,
    private userService: UserService,
    private localstorage: LocalstoreService
  ) { }

  ngOnInit() {
    const getUserInfo = this.store.select(fromUserState.getUserInfo)
      .subscribe((userInfo: UserInfo) => {
        if(!userInfo) return;
        this.userId = userInfo.id;
        this.userInfo = userInfo;
        this.profile = this.profileBuilder(userInfo);
        this.forms = this.createForms(this.profile);
      });
    this.subscriptions.push(getUserInfo);
  }

  ngOnDestroy() {
    for(let i = 0; i < this.subscriptions.length; i++) {
      this.subscriptions[i].unsubscribe();
    }
    this.subscriptions = [];
  }

  getFormControl(name: string): FormControl {
    return this.forms.get(name) as FormControl;
  }

  editProfile(item: ProfileForm): void {
    item.edit = !item.edit;
    this.edit = true;
  }

  cancelEdit(): void {
    this.profile = this.profile.map(item => ({ ...item, edit: false }));
    this.forms = this.createForms(this.profile);
    this.edit = false;
  }

  resetPassword(): void {
    this.modalService.open({
      title: '修改密码',
      content: ResetPasswordComponent,
      footer: false,
      maskClosable: false
    })
    .on('onOk', () => this.handleResetPasswordSuccess());
  }

  submitForm(event: Event): void {
    for (const i in this.forms.controls) {
      this.forms.controls[ i ].markAsDirty();
    }
    if(this.forms.valid) {
      this.loading = true;
      const updateProfile = this.userService.updateProfile(this.userId, this.forms.value)
        .subscribe((userInfo: UserInfo) => {
          this.store.dispatch(new LoadUserInfoSuccess(userInfo));
          this.loading = false;
          this.cancelEdit();
          this.notification.success('更新成功', '您的个人信息更新成功！');
        }, (error: ResponseError) => {
          this.notification.error('更新失败', '您的个人信息更新失败，请重试！');
        });
      this.subscriptions.push(updateProfile);
    }
  }

  private profileBuilder(userInfo: UserInfo): ProfileForm[] {
    const keys: object = {
      username: '用户名',
      realname: '昵称',
      email: '邮箱'
    };
    const allowNull: object = {};
    const uneditable: object = { username: true };
    const emails: object = { email: true };
    return Object.keys(keys)
      .map(key => ({ 
        key, 
        alias: keys[key],
        value: userInfo[key], 
        edit: false,
        editable: !uneditable[key],
        required: !allowNull[key],
        email: !!emails[key]
      }));
  }

  private createForms(profile: ProfileForm[]): FormGroup {
    const forms: FormGroup = this.fb.group(
      profile.reduce((controls, item) => {
        const validators: any[] = [];
        if(item.required) validators.push(Validators.required);
        if(item.email) validators.push(Validators.email);
        return {
          ...controls,
          [item.key]: [item.value || '', validators]
        };
      }, {})
    );
    return forms;
  }

  private handleResetPasswordSuccess(): void {
    const userToken: UserToken = this.localstorage.getItem('USER_TOKEN');
    this.localstorage.removeItem('USER_TOKEN');
    this.modalService.success({
      title: '修改成功',
      content: '您的密码已修改成功，点击“确定”按钮立即重新登录！',
      maskClosable: false,
      okText: '确定',
      onOk: () => {
        this.store.dispatch(new UserLogout(userToken));
        return new Promise((resolve) => {
          const getUserLogouted = this.store.select(fromUserState.getUserLogouted).subscribe(state => {
            if(state) {
              resolve();
              this.router.navigate(['/login']);
            }
          });
          this.subscriptions.push(getUserLogouted);
        });
      }
    });
  }

}
